/**
 * Crazy Toolbar
 *  @license by CrazyYi.
 *  @version v1.0.0 20200207
 *           v1.1.0 20200215: 支持 row、rowDouble 事件
 *           v1.2.0 20200323: 优化 toolbar 头工具栏处理
 *
 *  Only use for table data process
 *
 */
layui.define(['table', 'jquery', 'layer', 'crazyTool', 'crazyQuery', 'crazyHttp', 'crazyData'], function (exports) {
    const MOD_NAME = 'crazyToolbar'

    let $ = layui.jquery,
        crazyTool = layui.crazyTool,
        $table = layui.crazyQuery,
        $Http = layui.crazyHttp,
        $Data = layui.crazyData,
        layer = layui.layer

    /**
     * 保存主表的 options信息：在done回调中获取到
     * @type {{}}
     */
    let gMainTable = {};
    /**
     * 保存主表返回的数据
     * @type {{}}
     */
    let gRes = {};
    let gData = [];

    let tbFilter = '';
    let gOptions = {
        on: true,
        logOn: false,
        tool: [],
        toolbar: [],
        edit: [],
        row: [],
        rowDouble: [],
    };
    // 当前支持的event
    const gSupportEvent = ['tool', 'toolbar', 'row', 'rowDouble'];
    let gHttp = {};
    let gPKey = {};
    let gOpt = {
        event: 'edit', // 事件名，对应toolbar 中lay-event 对应的名称
        httpType: undefined, // http操作名称，对应 httpConfig 中的属性CURD：create, delete, update, read
        http: {
            mode: 'local', url: '', method: 'get', where: {}, jump: false, success: '', error: '',
        }, // 可以自定义，未定义则直接继承httpConfig[httpType] 的值

        fields: [], // url请求的where中所传递参数的名称，这些参数名在表中存在，url会把对应的参数名和在该记录的取值作为参数传递

        action: '', // 事件出发后，先执行 http请求，同时并发该action。该action中带有两个参数：obj, args
        args: {}, // action 函数的第二个参数，把action方法中需要额外获取的变量和取值传递过去
    };

    // tool 事件
    const _tool = {
        delete: function (o, d, obj) {
            d = d || obj.data || undefined;
            if (!d) {return}

            let sContent = "删除后，将再也无法找回。 <br/><br/> 确认删除吗?";
            layer.confirm(sContent, {btn: ['确定', '放弃']}, function (index) {
                let params = o.http;
                params.where = params.where || {};
                params.where[gPKey.name] = d[gPKey.field]; // 任何一个请求，都要把索引带上
                params.obj = obj;
                params.success = function () {obj.del()};
                $Http.httpReq(params);
                layer.close(index);

                o.action && typeof o.action === 'function' && o.action(obj, o.args); // 调用action
            }, function (index) {
                layer.msg('放弃本次操作');
            });
        },
        read: function (o, d, obj) {
            this.process(o, d, obj);
        },
        status: function (o, d, obj) {

        },
        process: function (o, d, obj) {
            d = d || obj.data || undefined;
            if (!d) {return}

            // 如果有url，则发起请求
            let h = o.http;
            let w = h.where || {};
            w[gPKey.name] = d[gPKey.field]; // 任何一个请求，都要把索引带上
            if (!!h.url) {
                $.each(o.fields, function (i, f) {
                    !!d[f] ? w[f] = d[f] : ''; // 传递当前记录对应的取值
                });
                $.extend(w, o.args); // 将args 也合并进来
                h.where = w;
                log.print('tool where =>', w);
                $Http.httpReq(h);
            }

            o.action && typeof o.action === 'function' && o.action(obj, o.args); // 调用action
        },
    };

    // toolbar 事件
    const _toolbar = {
        create: function (o, obj, checkStatus) {
            this.process(o, obj, checkStatus);
        },
        process: function (o, obj, checkStatus) {
            let res = true;
            $.extend(obj, checkStatus);
            obj['config'] = o;
            o.action && typeof o.action === 'function' && (res = o.action(obj)); // 调用action
            !!res && o.http && $Http.httpReq(o.http);
        },
    };

    // 监听 row 单双击事件
    const _row = {
        click: function (o, obj) {
            o.action && typeof o.action === 'function' && o.action(obj, o.args); // 调用action
        },
        dblclick: function (o, obj) {
            o.action && typeof o.action === 'function' && o.action(obj, o.args); // 调用action
        },
    };

    const classInit = {
        render: function () {
            // 1.加载 预处理模块
            this.http();
            this.table();
            this.data();

            // 2.加载 配置
            this.options();
        },
        options: function () {
            $.extend(gOptions, gMainTable.event);
            if (!gOptions) {return;}
            // 针对 所有的 toolbar 类型，进行处理
            $.each(gSupportEvent, function (j, s) {
                !!gOptions[s] && $.each(gOptions[s], function (i, o) {
                    let nO = gOpt.deepClone();
                    $.extend(nO, o);
                    if (!!nO.httpType) {
                        let t = gHttp[nO.httpType];
                        if (!!t) {
                            $.extend(nO.http, t); // 将 httpConfig[httpType] 的值 extend 到当前的Option
                        }
                    }
                    nO.fields = nO.fields || [];
                    gOptions[s][i] = nO;
                })
            });

            log.print('tool options', gOptions);
        },
        http: function () {
            gPKey = $Http.getPKey();
            gHttp = $Http.options();
        },
        table: function () {
            tbFilter = $table.tbFilter(); // 获取表格的过滤器
        },
        data: function () {
            ($Data.getCount && typeof $Data.getCount === 'function') && ($Data.getCount() || $Data.render(gMainTable, gRes));
        },
    };

    let dataIns = {
        render: function (myTable, res) {
            console.log('--------- crazyTable Toolbar ------------------');
            gMainTable = myTable;
            gRes = res;
            gData = res.data;
            classInit.render();

            this.tool();
            this.toolbar();
            this.row();
            this.rowDouble();
        },

        tool: function () {
            // 监听 行toolbar 事件
            table.on(`tool(${tbFilter})`, function (obj) {
                log.print('tool obj:', obj);
                let d = obj.data;
                let e = obj.event;

                !!gOptions.tool && $.each(gOptions.tool, function (i, o) {
                    if (o.event === e) {
                        switch (o.httpType) {
                            case 'read':
                                _tool.read(o, d, obj);
                                break;
                            case 'delete':
                                _tool.delete(o, d, obj);
                                break;
                            default:
                                _tool.process(o, d, obj);
                        }
                    }
                });
            })
        },
        toolbar: function () {
            // 监听 头工具栏 事件
            table.on(`toolbar(${tbFilter})`, function (obj) {
                log.print('toolbar obj:', obj);
                // 采用 Data 的方法，返回结构：{data: rows, ids: ids, where: where}
                let checkStatus = $Data.checkDatas();
                let d = checkStatus.data;
                let e = obj.event;

                !!gOptions.toolbar && $.each(gOptions.toolbar, function (i, o) {
                    if (o.event === e) {
                        // 如果有url，则发起请求
                        switch (o.httpType) {
                            case 'create':
                                _toolbar.create(o, obj, checkStatus);
                                break;
                            default:
                                _toolbar.process(o, obj, checkStatus);
                        }
                    }
                });
            });
        },
        edit: function () {
            // 监听 行edit 事件
            table.on(`edit(${tbFilter})`, function (obj) {
                log.print('edit:', obj);
                // log.print(obj.value); //得到修改后的值
                // log.print(obj.field); //当前编辑的字段名
                // log.print(obj.data); //所在行的所有相关数据

                let d = obj.data;
                let e = obj.event;
                let where = {};
                where[gPKey.name] = d[gPKey.field]; // 任何一个请求，都要把索引带上

                !!gOptions.edit && $.each(gOptions.edit, function (i, o) {
                    if (o.event === obj.event) {
                    }
                });
            });
        },
        row: function () {
            // 监听 行toolbar 事件
            table.on(`row(${tbFilter})`, function (obj) {
                log.print('row click obj:', obj);
                let d = obj.data;
                let e = obj.event;
                !!gOptions.row && $.each(gOptions.row, function (i, o) {
                    _row.click(o, obj);
                });
            })
        },
        rowDouble: function () {
            // 监听 行toolbar 事件
            table.on(`rowDouble(${tbFilter})`, function (obj) {
                log.print('row double obj:', obj);
                let d = obj.data;
                let e = obj.event;
                !!gOptions.rowDouble && $.each(gOptions.rowDouble, function (i, o) {
                    if (obj.event === o.event) {
                        _row.dblclick(o, obj);
                    }
                });
            })
        },
    };

    const log = {
        /**
         * 打印Log
         * @returns {boolean}
         */
        print: function () {
            let logOn = gOptions.logOn || false;
            if (!logOn) return false;
            const tips = 'crazyTable Toolbar';
            console.log(tips + ' | ', arguments[0], arguments[1] || '',
                arguments[2] || '', arguments[3] || '', arguments[4] || '', arguments[5] || '');
            return true;
        },
    };

    /**
     * 输出接口 gTable
     */
    exports(MOD_NAME, dataIns);
});